#include "Mylogger.hh"
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <iostream>
#include <cstring> // 添加 strrchr 支持

using namespace log4cpp;

Mylogger * Mylogger::_pInstance = nullptr;

Mylogger::Mylogger()
: _mycat(Category::getRoot().getInstance("mycat"))
{
    auto ptn1 = new PatternLayout();
    //ptn1->setConversionPattern("%d %c [%p] %m%n");
    ptn1->setConversionPattern("[%p] %m%n");

    auto ptn2 = new PatternLayout();
    ptn2->setConversionPattern("%d %c [%p] %m%n");

    auto pos = new OstreamAppender("console", &std::cout);
    pos->setLayout(ptn1);

    auto pfile = new FileAppender("file","log/my.log");
    pfile->setLayout(ptn2);

    _mycat.setPriority(Priority::DEBUG);
    _mycat.addAppender(pos);
    _mycat.addAppender(pfile);
    //_mycat.setAdditivity(pfile);

    std::cout << "Mylogger initialized" << std::endl;
}

Mylogger::~Mylogger()
{
    Category::shutdown();
    std::cout << "~Mylogger()" << std::endl;
}

Mylogger * Mylogger::getInstance()
{
    if(!_pInstance) {
        _pInstance = new Mylogger();
    }
    return _pInstance;
}

void Mylogger::destroy()
{
    if(_pInstance) {
        delete _pInstance;
        _pInstance = nullptr;
    }
}

std::string Mylogger::addPrefix(const char* file, const char* func, int line, const std::string& msg)
{
    // 提取文件名（不含路径）
    const char* baseName = strrchr(file, '/');
    if (!baseName) baseName = strrchr(file, '\\');
    baseName = baseName ? baseName + 1 : file;
    
    // 使用字符串流构建前缀
    std::ostringstream oss;
    oss << "[" << baseName << ":" << func << ":" << line << "] " << msg;
    return oss.str();
}

std::string Mylogger::formatMessage(const char* fmt, va_list args)
{
    // 计算所需缓冲区大小
    va_list args_copy;
    va_copy(args_copy, args);
    int length = vsnprintf(nullptr, 0, fmt, args_copy);
    va_end(args_copy);
    
    if (length <= 0) return "[Format Error]";
    
    // 创建缓冲区并格式化
    std::vector<char> buffer(length + 1);
    vsnprintf(buffer.data(), buffer.size(), fmt, args);
    
    return std::string(buffer.data(), length);
}

void Mylogger::log(log4cpp::Priority::Value priority, 
                   const char* file, const char* func, int line, 
                   const char* fmt, va_list args)
{
    // 格式化用户消息
    std::string formatted = formatMessage(fmt, args);
    
    // 添加位置前缀
    std::string fullMessage = addPrefix(file, func, line, formatted);
    
    // 根据优先级记录日志
    switch(priority) {
        case Priority::WARN:
            _mycat.warn(fullMessage);
            break;
        case Priority::ERROR:
            _mycat.error(fullMessage);
            break;
        case Priority::DEBUG:
            _mycat.debug(fullMessage);
            break;
        case Priority::INFO:
            _mycat.info(fullMessage);
            break;
        default:
            _mycat.warn(fullMessage); // 默认为警告级别
    }
}

// 实现各个日志级别的函数
void Mylogger::warn(const char* file, const char* func, int line, const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    log(Priority::WARN, file, func, line, fmt, args);
    va_end(args);
}

void Mylogger::error(const char* file, const char* func, int line, const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    log(Priority::ERROR, file, func, line, fmt, args);
    va_end(args);
}

void Mylogger::debug(const char* file, const char* func, int line, const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    log(Priority::DEBUG, file, func, line, fmt, args);
    va_end(args);
}

void Mylogger::info(const char* file, const char* func, int line, const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    log(Priority::INFO, file, func, line, fmt, args);
    va_end(args);
}